package ru.fizteh.fivt.demo.calc;

import ru.fizteh.fivt.demo.ntypes.MyNumber;
import ru.fizteh.fivt.demo.ntypes.MyNumberFormatException;
import ru.fizteh.fivt.demo.ntypes.*;

import Ice.Current;

public class CalcNumberImpl extends _CalcNumberDisp {
	
	Ice.Logger log;
	public CalcNumberImpl(Ice.Logger _log)	{
		super();
		log=_log;
	}
	
	public CalcNumberImpl()	{
		super();
	}
	public MyNumber add(MyNumber x, MyNumber y, Current __current) throws MyNumberFormatException {
		// Auto-generated method stub
		log.print("+");
		return new MyNumberFloat(
				number2float(x) + number2float(y)
				);
	}

	public MyNumber mult(MyNumber x, MyNumber y, Current __current) throws MyNumberFormatException {
		// Auto-generated method stub
		log.print("*");
		return new MyNumberFloat(
				number2float(x) * number2float(y)
				);
	}

	public MyNumber div(MyNumber x, MyNumber y, Current __current) throws DivByZeroException, MyNumberFormatException {
		// Auto-generated method stub
		log.print("/");
		float res = number2float(x)/number2float(y);
		if (Math.abs(res) > Float.MAX_VALUE)
			throw new DivByZeroException();
		
		return new MyNumberFloat(res);
	}

	/**
	 * Converts Number value to float
	 * @return float value
	 * @throws NumberFormat
	 */
	private float number2float(MyNumber v) throws MyNumberFormatException	{
		if (v.ice_isA(MyNumberFloat.ice_staticId()))	{
			// v is NumberFloat
			float fv = ((MyNumberFloat)v).value;
			log.print("" + fv);
			return fv;
		}
		
		if (v.ice_isA(MyNumberString.ice_staticId()))	{
			// v is NumberString
			String sValue = ((MyNumberString)v).value;
			log.print("" + sValue);
			float fValue;
			try	{
				fValue = Float.parseFloat(sValue);
				return fValue;
			}	catch (java.lang.NumberFormatException ex)	{
				throw new MyNumberFormatException("Malformed NumberString: [" + sValue + "]");
			}
		}
		
		throw new MyNumberFormatException("Unknown number type: [" + v.ice_id() + "]");
	}
	
}
